package com.hanxiaozhang.unionfindset;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 〈一句话功能简述〉<br>
 * 〈合并用户实体〉
 *
 * @author hanxinghua
 * @create 2021/9/25
 * @since 1.0.0
 */
public class MergeUser {

    /**
     * 如果两个用户的某个字段相同，就为同一个用户。合并所有用户，返回用户个数
     *
     * @param args
     */
    public static void main(String[] args) {

        List<User> users = new ArrayList<>();

        users.add(new User("ab", "cv", "cd"));
        users.add(new User("ab", "cv2", "cd2"));
        users.add(new User("ab1", "cv", "cd2"));
        users.add(new User("ab4", "cv2", "cd2"));
        users.add(new User("ab2", "cv4", "cd3"));

        System.out.println(mergeUser(users));
    }


    /**
     * 合并用户
     * 思路：
     * 申请三个map存储<属性名称，对象>格式信息，使用unionFindSet.union()，
     * 将具有相同属性两个实体合并。
     * 最后调用unionFindSet.size()，返回合并之后的个数
     *
     * @param users
     * @return
     */
    public static int mergeUser(List<User> users) {

        UnionFindSet<User> unionFindSet = new UnionFindSet<>(users);

        HashMap<String, User> mapA = new HashMap<>(16);
        HashMap<String, User> mapB = new HashMap<>(16);
        HashMap<String, User> mapC = new HashMap<>(16);


        for (User user : users) {
            if (mapA.containsKey(user.a)) {
                unionFindSet.union(user, mapA.get(user.a));
            } else {
                mapA.put(user.a, user);
            }
            if (mapB.containsKey(user.b)) {
                unionFindSet.union(user, mapB.get(user.b));
            } else {
                mapB.put(user.b, user);
            }
            if (mapC.containsKey(user.c)) {
                unionFindSet.union(user, mapC.get(user.c));
            } else {
                mapC.put(user.c, user);
            }
        }

        //向并查集询问合并之后，还有多个集合
        return unionFindSet.size();
    }

    public static class User {

        public String a;
        public String b;
        public String c;

        public User(String a, String b, String c) {
            this.a = a;
            this.b = b;
            this.c = c;
        }
    }
}
